#include "plateau.h"

/*	DECLARATION	*/

int abs (int n);
int ecart (int a, int b);
int distance (Point a, Point b);
int longueur (Coup c);
int carre (int n);
int *grille_case (Grille &pGrille, Point p);
int *grille_case (Grille &pGrille, int x, int y);
int gety (int y);
bool align (Point a, Point b);
bool valid (Coup pCoup);
bool valid (Grille &pGrille, Coup c);
Joueur swap (Joueur player);


/*	DEFINITION	*/
	
int abs (int n) {
	if (n<0)
		return -n;
	return n;
}

int ecart (int a, int b) { return abs(a - b); }

int distance (Point a, Point b) {
	return carre(ecart(a.x, b.x)) + carre(ecart(a.y, b.y));
}

int longueur (Coup c) {
	return distance(c.a, c.b);
}

int carre (int n) { return n * n; }

int &grille_case (Grille &pGrille, Point p) {
	return pGrille.content[p.y * GRILLE_LARGEUR + p.x];
}

int &grille_case (Grille &pGrille, int x, int y) {
	return pGrille.content[y * GRILLE_LARGEUR + x];
}

int gety (int y) {
	return y * GRILLE_LARGEUR;
}

bool align (Point a, Point b) { return (a.x == b.x) || (a.y == b.y); }

bool valid (Coup pCoup) { return align(c.a, c.b); }

bool valid (Grille &pGrille, Coup c) {
	return grille_case(pGrille, c.b) == VIDE
		&& ((valid(c) && distance(c) <= 4) || (distance(c) == 1));
}

Joueur swap (Joueur player) {
	if (player == P1) {
		return P2;
	} else {
		return P1;
	}
}



/* ------------------------------ */


void swap (Plateau &pPlato);
void deplacer (Plateau &pPlato, Point a, Point b);
void placer (Plateau &pPlato, Point p, int val);
void contaminer (Plateau &pPlato, Point p);
void set_nbplayer (Plateau &pPlato, Joueur player, int val);

void swap (Plateau &pPlato) { pPlato.player = swap(pPlato.player); }

void deplacer (Plateau &pPlato, Point a, Point b) {
	grille_case(pPlato.grid, b) = grille_case(pPlato.grid, a);
	grille_case(pPlato.grid, a) = VIDE;
	grille_case(pPlato.territory, b) = val;
}

void placer (Plateau &pPlato, Point p, int val) {
	pPlato.grid.content[gety(p.y) + p.x] = val;
	pPlato.territory.content[gety(p.y) + p.x] = val;
}

void contaminer (Plateau &pPlato, Point p) {
	int i, j;
	Joueur other;
	
	other = swap(pPlato.player)
	
	for (i = p.x - 1; i <= p.x + 1; i++)
	for (j = p.y - 1; j <= p.y + 1; j++) {
		if (i != p.x && j != p.y) {
			if (pPlato.grid.content[j * GRILLE_LARGEUR + i] == other) {
				pPlato.grid.content[j * GRILLE_LARGEUR + i] = pPlato.player;
				set_territoryplayer(pPlato, pPlato.player, 1);
				set_territoryplayer(pPlato, other, -1);
				set_nbplayer(pPlato, pPlato.player, 1);
				set_nbplayer(pPlato, other, -1);
			}
			if (pPlato.territory.content[j * GRILLE_LARGEUR + i] == VIDE) {
				pPlato.territory.content[j * GRILLE_LARGEUR + i] = pPlato.player;
				set_territoryplayer(pPlato, pPlato.player, 1);
			}
		}
	}
}

void set_nbplayer (Plateau &pPlato, Joueur player, int val) {
	if (player == P1) {
		pPlato.nb_p1 += val;
	} else {
		pPlato.nb_p2 += val;
	}
}

void set_territoryplayer (Plateau &pPlato, Joueur player, int val) {
	if (player == P1) {
		pPlato.territory_p1 += val;
	} else {
		pPlato.territory_p2 += val;
	}
}

/* ------------------------------ */

void plateau_make (Plateau &pPlato) {
	int i;
	
	for (i=0; i< GRILLE_HAUTEUR * GRILLE_LARGEUR; i++)
		pPlato.grid[i] = VIDE;
	
	pPlato.player = P1;
}

void plateau_jouer (Plateau &pPlato, Coup &pCoup) {
	if (longueur(pCoup) == 4) {
		deplacer(pPlato, pCoup.a, pCoup.b);
	} else {
		placer(pPlato, pCoup.b, pPlato.player);
	}
	
	contaminer(pCoup.b);
	
	swap(pPlato);
}

bool plateau_valid (Plateau &pPlato, Coup &pCoup) {
	return valid(pPlato.grid) && pPlato.player == pCoup.player
}

void plateau_display (Plateau &pPlato) {
	plato.grid.content
}